package all_router

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"golang.org/x/time/rate"
	"net/http"
	"shangyuapi/data_source"
	"shangyuapi/models"
	"sync"
	"time"
)

type UserinfoBody struct {
	Uid int64 `json:"uid" gorm:"uid"`
}
type MyClaimsval struct {
	Userid int64 `json:"userid"`
	jwt.StandardClaims
}

func HelloMiddleware(rl *RateLimiter) gin.HandlerFunc {

	return func(c *gin.Context) {

		url := c.Request.URL
		if url.String() == "/user/usertoken" {
			c.Next()
		} else {
			clientIP := c.ClientIP()
			limiter := rl.GetLimiter(clientIP)

			if !limiter.Allow() {
				c.JSON(http.StatusOK, gin.H{
					"code":    0,
					"error":   0,
					"success": 200,
					"data":    "访问过快",
					"msg":     "ok",
				})
				c.Abort()
				return
			}
			//mySigninkkey := []byte("woshiyanwei199511111")
			//tokenval := c.Request.Header.Get("x-token")
			//tokeninfo, err := utils.AuthTokne(tokenval, mySigninkkey)
			//if err != nil {
			//	c.Abort()
			//	return
			//}
			//_, ok := c.Get(tokenval)
			//if !ok {
			//	c.Set(tokenval, tokeninfo.UserId)
			//}
			//if tokeninfo.UserId > 0 {
			//	rl.RecordUser(tokeninfo.UserId)
			//}
			c.Next()
		}

	}
}

// RateLimiter 结构体用于存储每个IP地址的限流器
type RateLimiter struct {
	ipToLimiter   map[string]*rate.Limiter
	mu            sync.Mutex
	recordedUsers map[int64]bool
}

// NewRateLimiter 创建一个新的 RateLimiter 实例
func NewRateLimiter(rps float64, burst int) *RateLimiter {
	return &RateLimiter{
		ipToLimiter:   make(map[string]*rate.Limiter),
		recordedUsers: make(map[int64]bool),
	}
}

// GetLimiter 获取指定IP地址的限流器，如果不存在则创建一个新的
func (rl *RateLimiter) GetLimiter(ip string) *rate.Limiter {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	limiter, exists := rl.ipToLimiter[ip]
	if !exists {
		limiter = rate.NewLimiter(rate.Every(1*time.Second), 5)
		rl.ipToLimiter[ip] = limiter
	}

	return limiter
}
func (ur *RateLimiter) RecordUser(userID int64) bool {

	ur.mu.Lock()
	defer ur.mu.Unlock()
	limiter, exists := ur.recordedUsers[userID]

	if !exists {
		ur.recordedUsers[userID] = true
		data_source.Db.Model(&models.User{}).Where("id = ?", userID).Update("update_time", time.Now().Unix())
	}
	return limiter
}
